using System;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web.Services;
using System.Web.Services.Protocols;
using CrmSdkHelperClass;
using CrmServiceWebReference;
using KalDev;
using Resources;

/// <summary>
/// ///
/// ///    Notes exceptions, exclusions, or any other funny's you need 
/// ///    to know about Case
/// ///
/// Liquid Thought
/// Created by:Rihan
/// 
/// </summary>
[WebService(Namespace = "http://LtMbs/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Case : WebService
{
    #region fields

    private static readonly int _searchResultsSystemIdentifierColumnId = 4;
    private email _email;
    private WebCaseCollection _webCases = new WebCaseCollection();
    private CrmService microsoftCrmWebService;

    #endregion fields

    /// <summary>
    /// Initializes a new instance of the <see cref="Case"/> class.
    /// </summary>
    public Case()
    {
        microsoftCrmWebService = Common.CrmAutorize();
    }

    /// <summary>
    /// Retreives the feedback.
    /// </summary>
    [WebMethod]
    public void RetreiveFeedback()
    {
        startImport();
        CreateWebCases();
        Common.updateConfigFile(DateTime.Now.ToString());
    }

    private void CreateWebCases()
    {
        foreach (WebCase webCase in _webCases)
        {
            if (webCase.HasBeenFoundInCrm != true)
            {
                create(webCase);
            }
        }
    }

    private void startImport()
    {
        ImportParameters parameters = new ImportParameters();
        parameters.Date = DateTime.Parse(getLastRunFeedbackDateTime());
        parameters.KmsWebCaseRefrenceNumber = 0;

        Import importWebCases = new Import(parameters);
        _webCases = importWebCases.WebCases;
    }

    private static string getLastRunFeedbackDateTime()
    {
        return ConfigurationManager.AppSettings["lastFeedbackRunDate"].ToString();
    }

    /// <summary>
    /// Converts the CRM email into incident.
    /// </summary>
    /// <param name="CrmEmailId">The CRM email id.</param>
    /// <returns></returns>
    [WebMethod]
    public string ConvertCrmEmailIntoIncident(string CrmEmailId)
    {
        Email emailBeingConverted = new Email();
        emailBeingConverted.EmailId = new Guid(CrmEmailId);
        emailBeingConverted.Load();

        CrmCase incident = new CrmCase();
        incident.SourceEmail = emailBeingConverted;
        incident.Create();

        Guid CreatedIncidentId;

        CreatedIncidentId = incident.IncedentId;
        incident.attachEmail();
        incident.DetachEmailFromQueue();

        return CreatedIncidentId.ToString();
    }

    /// <summary>
    /// Converts a email to a formated text string
    /// </summary>
    /// <param name="sourceEmail">The source _email, that will be used to create the case, based on its content</param>
    /// <returns>clear text string</returns>
    /// <remarks>
    /// This is according to spesification document Version 5 dated 29-08-2007
    /// </remarks>
    [Obsolete("not used", true)]
    private string convertEmail(email sourceEmail)
    {
        StringBuilder emailInformation = new StringBuilder();

        emailInformation.AppendFormat("{0} {1}", Resource.EmailDescriptionPrefix,
                                      Common.removeHTMLTags(sourceEmail.description));
        emailInformation.AppendLine();
        emailInformation.AppendFormat("{0} {1}", Resource.EmailSubjectPrefix, Common.removeHTMLTags(sourceEmail.subject));
        emailInformation.AppendLine();
        emailInformation.AppendFormat("{0} {1}", Resource.EmailFromPrefix, sourceEmail.sender);
        emailInformation.AppendLine();

        foreach (activityparty person in sourceEmail.cc)
        {
            emailInformation.Append(RetreiveEmailAddress(person));
        }
        foreach (activityparty person in sourceEmail.bcc)
        {
            emailInformation.Append(RetreiveEmailAddress(person));
        }
        return emailInformation.ToString();
    }

    /// <summary>
    /// Retreives the customer, if there is not a CRM email to work with
    /// </summary>
    /// <param name="emailAddress">The email address.</param>
    /// <param name="sourceFeedbackEntry">The source feedback entry.</param>
    /// <returns>CrmCustomer</returns>
    private static Customer RetreiveCustomer(string emailAddress, WebCase sourceFeedbackEntry)
    {
        Guid customerID = new Guid();
        //Uses all ready built search to retreive information
        DataTable results = CombinedSearch.Instance.Search(emailAddress);
        if (results.Rows.Count > 0)
        {
            string customerIdUnformated =
                results.Rows[0].ItemArray.GetValue(_searchResultsSystemIdentifierColumnId).ToString();
            switch (customerIdUnformated.Length)
            {
                case 38:
                    customerID =
                        new Guid(results.Rows[0].ItemArray.GetValue(_searchResultsSystemIdentifierColumnId).ToString());
                    break;
                case 32:
                    //Contact.CreateCrmContact(results.Rows[0].ItemArray.GetValue(_searchResultsSystemIdentifierColumnId).ToString());
                    throw new NotImplementedException();
                    break;
            }
        }
        else
        {
            if (sourceFeedbackEntry.ShopperId.Length > 1)
            {
                Contact customer = new Contact();
                customer.ShopperId = sourceFeedbackEntry.ShopperId;
                customer.CreateInCrm();

                customerID = customer.ContactIdInCrm;
            }
            else
            {
                customerID =
                    new Guid(
                        Contact.createUnknownContact(emailAddress, sourceFeedbackEntry.FirstName,
                                                     sourceFeedbackEntry.LastName));
            }
        }

        return CrmTypes.CreateCustomer(EntityName.contact.ToString(), customerID);
    }

    /// <summary>
    /// Retreives the email address from the activityparty
    /// </summary>
    /// <param name="person">Activity Party</param>
    /// <returns>string to be appended</returns>
    [Obsolete("not used", true)]
    private static string RetreiveEmailAddress(activityparty person)
    {
        StringBuilder emailAddress = new StringBuilder();
        emailAddress.AppendFormat("{0}", person.addressused);
        return emailAddress.ToString();
    }

    /// <summary>
    /// Retreives the feedback.
    /// </summary>
    /// <param name="feedbackEntryToReCreate">The feedback entry to re create.</param>
    private void create(WebCase webCase)
    {
        incident feedbackIncident = new incident();

        feedbackIncident.title = webCase.CustomerFeedbackID + " " + webCase.FeedbackCategoryList;
        feedbackIncident.new_kalahariwebsitereference = webCase.CustomerFeedbackID.ToString();
        feedbackIncident.new_ordernumber = webCase.ShortOrderId.ToString();
        feedbackIncident.customerid = RetreiveCustomer(webCase.Email, webCase);
        feedbackIncident.description = webCase.FeedbackMessage;
        feedbackIncident.caseorigincode = CrmTypes.CreatePicklist(int.Parse(Resource.ImportWebCaseOrginPickListId));

        Guid IncidentId = microsoftCrmWebService.Create(feedbackIncident);

        routeIncidentFromUsersWorkInProgressQueueToSupportQueue(IncidentId);
    }


    /// <summary>
    /// Routes the incident.
    /// </summary>
    /// <param name="IncidentToRoute">The incident to route.</param>
    private void routeIncidentFromUsersWorkInProgressQueueToSupportQueue(Guid IncidentToRoute)
    {
        TargetQueuedIncident incident = new TargetQueuedIncident();
        incident.EntityId = IncidentToRoute;

        RouteRequest request = new RouteRequest();
        request.Target = incident;
        request.RouteType = RouteType.Queue;
        request.EndpointId = new Guid(ConfigurationManager.AppSettings[Resource.AppSettingsSupportQueueId].ToString());
        request.SourceQueueId = Common.wipQueue().queueid.Value;

        RouteResponse response = (RouteResponse) microsoftCrmWebService.Execute(request);
    }

    /// <summary>
    /// Attaches the activity to incident.
    /// </summary>
    /// <param name="IncidentId">The incident id.</param>
    [Obsolete("not used", true)]
    private void attachActivityToIncident(Guid IncidentId)
    {
        email email = _email;
        email.regardingobjectid = CrmTypes.CreateLookup(EntityName.incident.ToString(), IncidentId);
        TargetUpdateEmail target = new TargetUpdateEmail();
        target.Email = email;

        UpdateRequest update = new UpdateRequest();
        update.Target = target;
        try
        {
            microsoftCrmWebService.Execute(update);
        }
        catch (SoapException soapError)
        {
            Common.LogErrorMessage(soapError);
        }
    }

    /// <summary>
    /// Routes the incident to users work in progress queue from the support queue
    /// </summary>
    /// <param name="IncidentId">The incident id.</param>
    [Obsolete("not used",true)]
    private void acceptIncident(Guid IncidentId)
    {
        TargetQueuedIncident target = new TargetQueuedIncident();
        target.EntityId = IncidentId;
        RouteRequest route = new RouteRequest();
        route.Target = target;
        route.EndpointId = microsoftCrmWebService.CallerIdValue.CallerGuid;
        route.RouteType = RouteType.User;

        RouteResponse response = (RouteResponse) microsoftCrmWebService.Execute(route);
    }

    /// <summary>
    /// Retreives the feedback.
    /// </summary>
    /// <param name="lastDateRun">The last date run.</param>
    /// <returns></returns>
    [Obsolete("not used", true)]
    private CustomerFeedbackResults RetreiveFeedback(string lastDateRun)
    {
        CRMService KalDevservice = Common.KmsAuthorize();
        CustomerFeedbackResults customerFeedbackResults = new CustomerFeedbackResults();
        customerFeedbackResults = KalDevservice.SearchCustomerFeedback(lastDateRun);
        return customerFeedbackResults;
    }

    /// <summary>
    /// Emails the out.
    /// </summary>
    /// <param name="emailId">The email id.</param>
    [Obsolete("not used", true)]
    private void EmailOut(Guid emailId)
    {
        TargetQueuedEmail target = new TargetQueuedEmail();
        target.EntityId = emailId;
        RouteRequest request = new RouteRequest();
        request.Target = target;
        request.RouteType = RouteType.Auto;
        request.SourceQueueId =
            new Guid(ConfigurationManager.AppSettings[Resource.AppSettingsSupportQueueId].ToString());
        try
        {
            microsoftCrmWebService.Execute(request);
        }
        catch (SoapException soapException)
        {
            Common.LogErrorMessage(soapException);
        }
    }

   
    [WebMethod]
    public void LaunchWorkFlow(string EntityId, string entityType, string WorkFlowId)
    {
        ExecuteWFProcessRequest request = new ExecuteWFProcessRequest();
        request.ProcessId = new Guid(WorkFlowId);
        request.EntityMoniker = new Moniker();
        request.EntityMoniker.Name = entityType.ToString();
        request.EntityMoniker.Id = new Guid(EntityId);

        ExecuteWFProcessResponse response = (ExecuteWFProcessResponse) microsoftCrmWebService.Execute(request);
    }
}